<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        class MyPromise {
            //构造函数，根据参数创建一个 Promise 对象
            constructor(executor) {
                //MyPromise的成员变量，实例化的MyPromise对象会拥有这些成员变量
                this.state = 'pending'; // 初始状态为 pending
                this.value = undefined; // 成功时的结果值：PromiseResult,二选一
                this.reason = undefined; // 失败时的结果值：PromiseResult，二选一

                this.onFulfilledCallbacks = []; // 存储成功的回调函数
                this.onRejectedCallbacks = []; // 存储失败的回调函数

                const resolve = (value) => {
                    if (this.state === 'pending') {
                        this.state = 'fulfilled';
                        this.value = value;
                        this.onFulfilledCallbacks.forEach(callback => callback());
                    }
                };

                const reject = (reason) => {
                    if (this.state === 'pending') {
                        this.state = 'rejected';
                        this.reason = reason;
                        this.onRejectedCallbacks.forEach(callback => callback());
                    }
                };

                try {
                    executor(resolve, reject);
                } catch (error) {
                    reject(error);
                }
            }
            // promise的成员函数：then返回一个新的 Promise 对象
            /**
            * then功能：根据传入的回调函数的return值，返回一个新的promise对象，
            * @param {*} callback
            *回调函数的参数是上一个promise对象的结果值
            *回调函数的返回值(经过处理后)将作为新promise的结果值
            *处理方式：如果是非promise对象，则直接作为新promise的结果值
            *如果是promise对象，则取出该promise对象的结果值，作为新的promise的结果值
            * @returns 新的promise对象
            */
            then(onFulfilled, onRejected) {
                onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
                onRejected = typeof onRejected === 'function' ? onRejected : error => { throw error };

                let promise2 = new MyPromise((resolve, reject) => {
                    const handle = (callback, value) => {
                        try {
                            let x = callback(value);
                            //处理回调函数的返回值
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (error) {
                            reject(error);
                        }
                    };

                    if (this.state === 'fulfilled') {
                        setTimeout(() => handle(onFulfilled, this.value), 0);
                    }

                    if (this.state === 'rejected') {
                        setTimeout(() => handle(onRejected, this.reason), 0);
                    }

                    if (this.state === 'pending') {
                        this.onFulfilledCallbacks.push(() => setTimeout(() => handle(onFulfilled, this.value), 0));
                        this.onRejectedCallbacks.push(() => setTimeout(() => handle(onRejected, this.reason), 0));
                    }
                });

                return promise2;
            }

            catch(onRejected) {
                return this.then(null, onRejected);
            }

            finally(onFinally) {
                return this.then(
                    value => {
                        return MyPromise.resolve(onFinally()).then(() => value);
                    },
                    error => {
                        return MyPromise.resolve(onFinally()).then(() => { throw error; });
                    }
                );
            }

            static resolve(value) {
                if (value instanceof MyPromise) {
                    return value;
                }

                return new MyPromise((resolve) => {
                    resolve(value);
                });
            }

            static reject(reason) {
                return new MyPromise((_, reject) => {
                    reject(reason);
                });
            }

            static all(promises) {
                return new MyPromise((resolve, reject) => {
                    const results = [];
                    let completed = 0;

                    if (promises.length === 0) {
                        resolve([]);
                        return;
                    }

                    promises.forEach((promise, index) => {
                        MyPromise.resolve(promise).then(
                            (value) => {
                                results[index] = value;
                                completed++;
                                if (completed === promises.length) {
                                    resolve(results);
                                }
                            },
                            (reason) => {
                                reject(reason);
                            }
                        );
                    });
                });
            }

            static race(promises) {
                return new MyPromise((resolve, reject) => {
                    promises.forEach((promise) => {
                        MyPromise.resolve(promise).then(
                            (value) => {
                                resolve(value);
                            },
                            (reason) => {
                                reject(reason);
                            }
                        );
                    });
                });
            }
        }

        // 辅助函数，用于处理 then 方法中返回的值
        function resolvePromise(promise2, x, resolve, reject) {
            // 检查是否存在循环引用，即 promise2 和 x 是否是同一个对象
            if (promise2 === x) {
                return reject(new TypeError('Chaining cycle detected for promise'));
            }

            // 定义一个标志变量，防止多次调用 resolve 或 reject
            let called;

            // 检查 x 是否为对象或函数
            if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
                try {
                    // 获取 x 的 then 方法
                    let then = x.then;

                    // 如果 x 有 then 方法，说明 x 可能是一个 Promise 对象
                    if (typeof then === 'function') {
                        // 调用 x 的 then 方法
                        then.call(x, y => {
                            // 如果已经调用过 resolve 或 reject，则不再执行
                            if (called) return;
                            called = true;

                            // 递归调用 resolvePromise，处理 y 的值
                            resolvePromise(promise2, y, resolve, reject);
                        }, err => {
                            // 如果已经调用过 resolve 或 reject，则不再执行
                            if (called) return;
                            called = true;

                            // 调用 reject，处理错误
                            reject(err);
                        });
                    } else {
                        // 如果 x 没有 then 方法，说明 x 不是一个 Promise 对象
                        // 直接调用 resolve，将 x 作为结果值
                        resolve(x);
                    }
                } catch (e) {
                    // 如果在获取 then 方法或调用 then 方法时发生错误
                    // 调用 reject，处理错误
                    if (called) return;
                    called = true;
                    reject(e);
                }
            } else {
                // 如果 x 是一个基本类型值（如字符串、数字、布尔值等）
                // 直接调用 resolve，将 x 作为结果值
                resolve(x);
            }
        }

        const myPromise = new MyPromise((resolve, reject) => {
            resolve(42);
            // reject('Error');
        });

        console.log(myPromise.state); // 输出：pending
        console.log(myPromise.value); // 输出：42
        console.log(myPromise.reason); // 输出：undefined
    </script>
</body>

</html>